package com.ui.basic.service.admin;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.jsecurity.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.common.basic.util.Globals;
import com.ui.basic.command.CommandRole;
import com.ui.basic.dao.assembler.RoleAssembler;
import com.ui.basic.ibatis.dao.system.TblSMenuDAO;
import com.ui.basic.ibatis.dao.system.TblSRoleDAO;
import com.ui.basic.ibatis.dao.system.TblSRoleMenusDAO;
import com.ui.basic.ibatis.model.system.TblSMenu;
import com.ui.basic.ibatis.model.system.TblSMenuExample;
import com.ui.basic.ibatis.model.system.TblSRole;
import com.ui.basic.ibatis.model.system.TblSRoleExample;
import com.ui.basic.ibatis.model.system.TblSRoleMenusExample;
import com.ui.basic.ibatis.model.system.TblSRoleMenusKey;

@Service("roleService")
public class RoleServiceImpl implements RoleService {
	private static final transient org.apache.commons.logging.Log LOGGER = org.apache.commons.logging.LogFactory
			.getLog(RoleServiceImpl.class);

	@Autowired
	private TblSRoleDAO tblSRoleDAO;
	@Autowired
	private TblSMenuDAO tblSMenuDAO;
	@Autowired
	private TblSRoleMenusDAO tblSRoleMenusDAO;

	public void setTblSRoleDAO(TblSRoleDAO tblSRoleDAO) {
		this.tblSRoleDAO = tblSRoleDAO;
	}

	public void setTblSMenuDAO(TblSMenuDAO tblSMenuDAO) {
		this.tblSMenuDAO = tblSMenuDAO;
	}

	public void setTblSRoleMenusDAO(TblSRoleMenusDAO tblSRoleMenusDAO) {
		this.tblSRoleMenusDAO = tblSRoleMenusDAO;
	}

	@Transactional(readOnly = true)
	public CommandRole getRole(CommandRole commandRole) throws SQLException {
		LOGGER.debug(">>>RoleServiceImpl.getRole");
		if (commandRole != null) {
			TblSRoleExample example = new TblSRoleExample();

			int rec = 0;
			try {
				rec = tblSRoleDAO.countByExample(example);
			} catch (NullPointerException npe) {
				LOGGER.error(npe);
			}
			commandRole.calculate(rec);
			example.setIntRowNum((commandRole.getPgIndex() - 1)
					* commandRole.getPgRows());
			example.setIntRowsPerPage(commandRole.getPgRows());
			example.setOrderByClause("ROLE_NAME");
			commandRole.setData(tblSRoleDAO.selectByExample(example));
		}
		return commandRole;
	}
	
	@Transactional(readOnly = true)
	public CommandRole getRoleDetail(CommandRole commandRole)
			throws SQLException {
		LOGGER.debug(">>>RoleServiceImpl.getRoleDetail");

		TblSRoleMenusExample example = new TblSRoleMenusExample();
		example.createCriteria().andRoleIdEqualTo(commandRole.getId());
		List<TblSRoleMenusKey> menuKeyList = tblSRoleMenusDAO
				.selectByExample(example);
		Long[] menuKey = getMenuKey(menuKeyList);

		commandRole.setRoleMenu(menuKey);
		commandRole.setProperty(tblSRoleDAO.selectByPrimaryKey(commandRole
				.getId()));

		return commandRole;
	}

	@Transactional(readOnly = true)
	public Collection<TblSMenu> getMenuColl() throws SQLException {
		LOGGER.debug(">>>RoleServiceImpl.getMenuColl");

		TblSMenuExample example = new TblSMenuExample();
		example.setOrderByClause("MENU_CODE");

		return tblSMenuDAO.selectByExample(example);
	}

	@Transactional
	public void save(CommandRole commandRole) throws SQLException {
		LOGGER.debug(">>>RoleServiceImpl.save");
		RoleAssembler assembler = new RoleAssembler();
		TblSRole role = assembler.toEntity(commandRole);

		if (commandRole.getId() != null) {
			role.setChangedby((String) (SecurityUtils.getSubject().getSession()
					.getAttribute(Globals.CURRENT_USER_NAME)));
			role.setChangeddate(new Date());
			try {
				tblSRoleDAO.updateByPrimaryKeySelective(role);
				
				TblSRoleMenusExample example = new TblSRoleMenusExample();
				example.createCriteria().andRoleIdEqualTo(role.getId());
				
				tblSRoleMenusDAO.deleteByExample(example);
				
				TblSRoleMenusKey tblSRoleMenusKey = new TblSRoleMenusKey();
				tblSRoleMenusKey.setRoleId(role.getId());
				for(Long menuKey: commandRole.getRoleMenu()){
					tblSRoleMenusKey.setMenuId(menuKey);
					tblSRoleMenusDAO.insert(tblSRoleMenusKey);
				}
			} catch (SQLException e) {
				LOGGER.error("***SQL Code == " + e.getErrorCode());
				LOGGER.error("***error msg == " + e.getMessage());
				throw e;
			}
		} else {
			role.setCreatedby((String) (SecurityUtils.getSubject().getSession()
					.getAttribute(Globals.CURRENT_USER_NAME)));
			role.setCreateddate(new Date());
			try {
				tblSRoleDAO.insert(role);
				
				TblSRoleExample example = new TblSRoleExample();
				example.createCriteria().andRoleNameEqualTo(role.getRoleName());
				
				role = (TblSRole) tblSRoleDAO.selectByExample(example).get(0);
				commandRole.setId(role.getId());
				
				TblSRoleMenusKey tblSRoleMenusKey = new TblSRoleMenusKey();
				tblSRoleMenusKey.setRoleId(role.getId());
				for(Long menuKey: commandRole.getRoleMenu()){
					tblSRoleMenusKey.setMenuId(menuKey);
					tblSRoleMenusDAO.insert(tblSRoleMenusKey);
				}

			} catch (SQLException e) {
				LOGGER.error("***SQL Code == " + e.getErrorCode());
				LOGGER.error("***error msg == " + e.getMessage());
				throw e;
			}
		}
	}

	protected Long[] getMenuKey(List<TblSRoleMenusKey> menuKeyList){
		LOGGER.debug(">>>RoleServiceImpl.getMenuKey");
		Long[] menuKey;
		if (menuKeyList != null && menuKeyList.size() > 0) {
			menuKey = new Long[menuKeyList.size()];
			int i = 0;
			for (TblSRoleMenusKey key : menuKeyList) {
				menuKey[i] = key.getMenuId();
				i++;
			}
		} else {
			menuKey = new Long[0];
		}
		return menuKey;
	}

	@Transactional
	public void delete(CommandRole commandRole) throws SQLException {
		LOGGER.debug(">>>RoleServiceImpl.delete");
		TblSRoleExample example = new TblSRoleExample();
		TblSRoleMenusExample example2 = new TblSRoleMenusExample();
		
		if(commandRole.getId()!=null){
			example.createCriteria().andIdEqualTo(commandRole.getId());
			example2.createCriteria().andRoleIdEqualTo(commandRole.getId());
		}else if(commandRole.getSelectedRecord()!=null && commandRole.getSelectedRecord().length>0){
			List<Long> idList = new ArrayList<Long>();
			for(String strId: commandRole.getSelectedRecord())
				idList.add(Long.valueOf(strId));
			example.createCriteria().andIdIn(idList);
			example2.createCriteria().andRoleIdIn(idList);
		}
		
		tblSRoleMenusDAO.deleteByExample(example2);
		tblSRoleDAO.deleteByExample(example);	
	}
}